<script>
import events from './events';
import { mapMutations } from 'vuex';

export default {
    name: 'MultiTab',
    data() {
        return {
            fullPathList: [], // 储存 $route.fullPath
            pages: [], // 储存 $route完整对象
            activeKey: '',
            newTabIndex: 0,
        };
    },
    created() {
        // bind event
        events
            .$on('open', (val) => {
                if (!val) {
                    throw new Error(`multi-tab: open tab ${val} err`);
                }
                this.activeKey = val;
            })
            .$on('close', (val) => {
                if (!val) {
                    this.closeThat(this.activeKey);
                    return;
                }
                this.closeThat(val);
            })
            .$on('rename', ({ key, name }) => {
                console.log('rename', key, name);
                try {
                    const item = this.pages.find((item) => item.path === key);
                    item.meta.customTitle = name;
                    this.$forceUpdate();
                } catch (e) {
                    console.log(e);
                }
            });

        this.pages.push(this.$route);
        this.fullPathList.push(this.$route.fullPath);
        this.selectedLastPath();
    },
    methods: {
        // 将 `this.SET_MULTI_TAB()` 映射为 `this.$store.commit('SET_MULTI_TAB')`
        ...mapMutations([
            'SET_MULTI_TAB',
            'ADD_EXCLUDE_VIEW',
            'DEL_EXCLUDE_VIEW',
        ]),
        onEdit(targetKey, action) {
            this[action](targetKey);
        },
        remove(targetKey) {
            // 关闭的页面
            const closedRoute = this.pages.find(
                (item) => item.fullPath === targetKey
            );
            this.pages = this.pages.filter(
                (page) => page.fullPath !== targetKey
            );
            this.fullPathList = this.fullPathList.filter(
                (path) => path !== targetKey
            );
            // this.$store.state.multiTab.excludeViews 中加入当前删除的路由，避免下次打开时组件没得到更新
            if (closedRoute.name) {
                this.ADD_EXCLUDE_VIEW(closedRoute);
            }
            // 判断当前标签是否关闭，若关闭则跳转到最后一个还存在的标签页
            if (!this.fullPathList.includes(this.activeKey)) {
                this.selectedLastPath();
            }
        },
        selectedLastPath() {
            this.activeKey = this.fullPathList[this.fullPathList.length - 1];
        },
        closeThat(e) {
            // 判断是否为最后一个标签页，如果是最后一个，则无法被关闭
            if (this.fullPathList.length > 1) {
                this.remove(e);
            } else {
                this.$message.info('这是最后一个标签了, 无法被关闭');
            }
        },
        closeLeft(e) {
            const currentIndex = this.fullPathList.indexOf(e);
            if (currentIndex > 0) {
                this.fullPathList.forEach((item, index) => {
                    if (index < currentIndex) {
                        this.remove(item);
                    }
                });
            } else {
                this.$message.info('左侧没有标签');
            }
        },
        closeRight(e) {
            const currentIndex = this.fullPathList.indexOf(e);
            if (currentIndex < this.fullPathList.length - 1) {
                this.fullPathList.forEach((item, index) => {
                    if (index > currentIndex) {
                        this.remove(item);
                    }
                });
            } else {
                this.$message.info('右侧没有标签');
            }
        },
        closeAll(e) {
            const currentIndex = this.fullPathList.indexOf(e);
            this.fullPathList.forEach((item, index) => {
                if (index !== currentIndex) {
                    this.remove(item);
                }
            });
        },
        closeMenuClick(key, route) {
            this[key](route);
        },
        renderTabPaneMenu(e) {
            return (
                <a-menu
                    {...{
                        on: {
                            click: ({ key }) => {
                                this.closeMenuClick(key, e);
                            },
                        },
                    }}
                >
                    <a-menu-item key="closeThat">关闭当前标签</a-menu-item>
                    <a-menu-item key="closeRight">关闭右侧</a-menu-item>
                    <a-menu-item key="closeLeft">关闭左侧</a-menu-item>
                    <a-menu-item key="closeAll">关闭全部</a-menu-item>
                </a-menu>
            );
        },
        // render
        renderTabPane(title, keyPath) {
            const menu = this.renderTabPaneMenu(keyPath);

            return (
                <a-dropdown overlay={menu} trigger={['contextmenu']}>
                    <span style={{ userSelect: 'none' }}>{title}</span>
                </a-dropdown>
            );
        },
    },
    watch: {
        $route: function (newVal) {
            this.activeKey = newVal.fullPath;
            if (this.fullPathList.indexOf(newVal.fullPath) < 0) {
                this.fullPathList.push(newVal.fullPath);
                this.pages.push(newVal);
            }
        },
        activeKey: function (newPathKey) {
            this.$router.push({ path: newPathKey });
        },
        fullPathList: function () {
            this.SET_MULTI_TAB(this.fullPathList);
            this.DEL_EXCLUDE_VIEW(this.$route);
        },
    },
    render() {
        const {
            onEdit,
            $data: { pages },
        } = this;
        const panes = pages.map((page) => {
            return (
                <a-tab-pane
                    style={{ height: 0 }}
                    tab={this.renderTabPane(
                        page.meta.customTitle || page.meta.title,
                        page.fullPath
                    )}
                    key={page.fullPath}
                    closable={pages.length > 1}
                ></a-tab-pane>
            );
        });

        return (
            <div class="ant-pro-multi-tab">
                <div class="ant-pro-multi-tab-wrapper">
                    <a-tabs
                        hideAdd
                        type={'editable-card'}
                        v-model={this.activeKey}
                        tabBarStyle={{
                            background: '#FFF',
                            margin: 0,
                            paddingLeft: '16px',
                            paddingTop: '1px',
                        }}
                        {...{ on: { edit: onEdit } }}
                    >
                        {panes}
                    </a-tabs>
                </div>
            </div>
        );
    },
};
</script>
